package com.tarena.lbs.basic.web.service.impl;

import com.github.pagehelper.PageInfo;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;

import com.tarena.lbs.basic.web.repository.DictItemRepository;
import com.tarena.lbs.basic.web.repository.DictRepository;
import com.tarena.lbs.basic.web.repository.TagLibraryRepository;
import com.tarena.lbs.basic.web.repository.UserTagsRepository;
import com.tarena.lbs.basic.web.service.ITagLibraryService;
import com.tarena.lbs.common.basic.converter.TagLibraryConverter;
import com.tarena.lbs.common.basic.enums.TagLibraryStatusEnum;
import com.tarena.lbs.pojo.basic.bo.DictBO;
import com.tarena.lbs.pojo.basic.bo.DictItemBO;
import com.tarena.lbs.pojo.basic.bo.TagLibraryBO;
import com.tarena.lbs.pojo.basic.dos.DictItemDO;
import com.tarena.lbs.pojo.basic.dos.TagLibraryDO;
import com.tarena.lbs.pojo.basic.dos.UserTagsDO;
import com.tarena.lbs.pojo.basic.param.TagLibraryParam;
import com.tarena.lbs.pojo.basic.query.DictItemQuery;
import com.tarena.lbs.pojo.basic.query.DictQuery;
import com.tarena.lbs.pojo.basic.query.TagLibraryQuery;
import com.tarena.lbs.pojo.basic.vo.TagLibraryVO;
import com.tarena.lbs.pojo.basic.vo.UserItemTag;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Service
public class TagLibraryServiceImpl implements ITagLibraryService {
    @Autowired
    private TagLibraryRepository tagLibraryRepository;

    @Autowired
    private DictItemRepository dictItemRepository;


    @Autowired
    private DictRepository dictRepository;

    @Autowired
    private TagLibraryConverter tagLibraryConverter;

    @Autowired
    private UserTagsRepository userTagsRepository;



    @Override
    public void save(TagLibraryParam tagLibraryParam) throws BusinessException {
      //  todo 检查标签唯一性
//
//        //查询tag_category(dict_item_id) == tag_name 唯一
        checkUniqueByTagTypeAndTagCategoryAndTagName(null, tagLibraryParam, "yes");

        TagLibraryDO tagLibraryDO = new TagLibraryDO();
        BeanUtils.copyProperties(tagLibraryParam, tagLibraryDO);
        Date date = new Date();
        //设置创建时间以及更新时间
        tagLibraryDO.setCreateAt(date);
        tagLibraryDO.setUpdateAt(date);
        //todo  生产唯一的 coding
        String uuid = UUID.randomUUID().toString();
        tagLibraryDO.setCoding(uuid);
        if (tagLibraryDO.getStatus()==null){
            tagLibraryDO.setStatus(TagLibraryStatusEnum.ACTIVE.getCode());
        }
        System.out.println(tagLibraryDO);
        tagLibraryRepository.insert(tagLibraryDO);
    }

    @Override
    public void delete(Integer id) {
        tagLibraryRepository.delete(id);
    }

    @Override
    public void update(Integer id, TagLibraryParam tagLibraryParam) throws BusinessException {
        checkUniqueByTagTypeAndTagCategoryAndTagName(id, tagLibraryParam, "yes");
        TagLibraryDO tagLibraryDO = new TagLibraryDO();
        BeanUtils.copyProperties(tagLibraryParam, tagLibraryDO);
        tagLibraryDO.setId(id);
        tagLibraryDO.setUpdateAt(new Date());
        tagLibraryRepository.update(tagLibraryDO);
    }

    @Override
    public TagLibraryBO detail(Integer id) {
         TagLibraryBO tagLibraryBO = tagLibraryRepository.detail(id);
        if (null == tagLibraryBO) {
            return null;
        }
        DictItemBO dictItemBO = dictItemRepository.detail(tagLibraryBO.getTagType());
        DictItemBO dictItemBO1 = dictItemRepository.detail(tagLibraryBO.getTagCategory());
        tagLibraryBO.setTagTypeName(dictItemBO == null ? "" :dictItemBO.getDictValue());
        tagLibraryBO.setTagCategoryName(dictItemBO1 == null ? "" :dictItemBO1.getDictValue());
        return tagLibraryBO;
    }

    @Override
    public PageResult<TagLibraryVO> list(TagLibraryQuery tagLibraryQuery) {
       // 加入分页
        int page = tagLibraryQuery.getPageNo();
        int pageSize = tagLibraryQuery.getPageSize();
        //new PageQuery(page, pageSize);
        List<Integer> statusList = new ArrayList<>();
        if (null == tagLibraryQuery.getStatus()) {
            statusList.add(TagLibraryStatusEnum.ACTIVE.getCode());
            statusList.add(TagLibraryStatusEnum.NOT_ACTIVE.getCode());
        } else {
            statusList.add(tagLibraryQuery.getStatus());
        }
        tagLibraryQuery.setStatusList(statusList);

        int tagType = tagLibraryQuery.getTagType();
        tagLibraryQuery.setTagType(tagType);
        List<TagLibraryDO> tagLibraryDOS= tagLibraryRepository.selectByCondition(tagLibraryQuery);
        PageInfo<TagLibraryDO> pageInfo = new PageInfo<>(tagLibraryDOS);

        List<TagLibraryVO> tagLibraryVOS = pageInfo.getList().stream().map(tagLibraryDO -> {
            TagLibraryVO tagLibraryVO = new TagLibraryVO();
            BeanUtils.copyProperties(tagLibraryDO, tagLibraryVO);
            DictItemBO dictItemBO = dictItemRepository.detail(tagLibraryDO.getTagType());
            DictItemBO dictItemBO1 = dictItemRepository.detail(tagLibraryDO.getTagCategory());
            tagLibraryVO.setTagTypeName(dictItemBO == null ? "" :dictItemBO.getDictValue());
            tagLibraryVO.setTagCategoryName(dictItemBO1 == null ? "" :dictItemBO1.getDictValue());
            return tagLibraryVO;
        }).collect(Collectors.toList());

        PageResult<TagLibraryVO> pageResult = new PageResult<>();
        pageResult.setObjects(tagLibraryVOS);
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setPageNo(page);
        pageResult.setPageSize(pageSize);
        return pageResult;
    }

    @Override
    public List<TagLibraryBO> articleList() throws BusinessException {

        DictQuery dictQuery = new DictQuery();
        dictQuery.setDictName("标签类型");
        DictBO dictBO = dictRepository.selectBOByCondition(dictQuery);
        if (dictBO==null){
            throw new BusinessException("10015","字典中标签类型不存在");
        }
        DictItemQuery dictItemQuery = new DictItemQuery();
        dictItemQuery.setDictId(dictBO.getId());
        dictItemQuery.setDictValue("内容");
        List<DictItemDO> dictItemDOS = dictItemRepository.selectByCondition(dictItemQuery);
        if (dictItemDOS.isEmpty()){
            throw new BusinessException("10016","字典数据中内容不存在");
        }
        TagLibraryQuery tagLibraryQuery = new TagLibraryQuery();
        for (DictItemDO dictItemDO: dictItemDOS) {
            tagLibraryQuery.setTagType(dictItemDO.getId());
        }
        tagLibraryQuery.setStatus(TagLibraryStatusEnum.ACTIVE.getCode());
        List<TagLibraryDO> tagLibraryDOS = tagLibraryRepository.selectByCondition(tagLibraryQuery);
        List<TagLibraryBO> tagLibraryBOS = tagLibraryConverter.doList2boList(tagLibraryDOS);
        return tagLibraryBOS;
    }

    @Override
    public Map<String, List<UserItemTag>> articleAllList() throws BusinessException {
        DictQuery dictQuery = new DictQuery();
        dictQuery.setDictName("标签类型");
        DictBO dictBO = dictRepository.selectBOByCondition(dictQuery);
        if (dictBO==null){
            throw new BusinessException("10015","字典中标签类型不存在");
        }
        DictItemQuery dictItemQuery = new DictItemQuery();
        dictItemQuery.setDictId(dictBO.getId());
        dictItemQuery.setDictValue("内容");
        List<DictItemDO> dictItemDOS = dictItemRepository.selectByCondition(dictItemQuery);
        if (dictItemDOS.isEmpty()){
            throw new BusinessException("10016","字典数据中内容不存在");
        }
        TagLibraryQuery tagLibraryQuery = new TagLibraryQuery();
        for (DictItemDO dictItemDO: dictItemDOS) {
            tagLibraryQuery.setTagType(dictItemDO.getId());
        }
        tagLibraryQuery.setStatus(TagLibraryStatusEnum.ACTIVE.getCode());
        List<TagLibraryDO> tagLibraryDOS = tagLibraryRepository.selectByCondition(tagLibraryQuery);
        List<TagLibraryBO> tagLibraryBOS = tagLibraryConverter.doList2boList(tagLibraryDOS);
        List<UserItemTag> userItemTagList = new ArrayList<>();
        for (TagLibraryBO tagLibraryBO: tagLibraryBOS) {
            UserItemTag userItemTag = new UserItemTag();
            DictItemBO detail = dictItemRepository.detail(tagLibraryBO.getTagCategory());
            userItemTag.setTagCategoryName(detail == null ? "" :detail.getDictValue());
            userItemTag.setTagLibraryBO(tagLibraryBO);
            userItemTagList.add(userItemTag);
        }
        Map<String, List<UserItemTag>> dataMap = userItemTagList.stream()
            .collect(Collectors.groupingBy(UserItemTag::getTagCategoryName));
        return dataMap;
    }

    @Override
    public Map<String, List<UserItemTag>> userList() throws BusinessException {
        DictQuery dictQuery = new DictQuery();
        dictQuery.setDictName("标签类型");
        DictBO dictBO = dictRepository.selectBOByCondition(dictQuery);
        if (dictBO==null){
            throw new BusinessException("10015","字典中标签类型不存在");
        }
        DictItemQuery dictItemQuery = new DictItemQuery();
        dictItemQuery.setDictId(dictBO.getId());
        dictItemQuery.setDictValue("用户");
        List<DictItemDO> dictItemDOS = dictItemRepository.selectByCondition(dictItemQuery);
        if (dictItemDOS.isEmpty()){
            throw new BusinessException("10016","字典数据中用户不存在");
        }
        TagLibraryQuery tagLibraryQuery = new TagLibraryQuery();
        for (DictItemDO dictItemDO: dictItemDOS) {
            tagLibraryQuery.setTagType(dictItemDO.getId());
        }
        tagLibraryQuery.setStatus(TagLibraryStatusEnum.ACTIVE.getCode());
        List<TagLibraryDO> tagLibraryDOS = tagLibraryRepository.selectByCondition(tagLibraryQuery);
        List<TagLibraryBO> tagLibraryBOS = tagLibraryConverter.doList2boList(tagLibraryDOS);
        List<UserTagsDO> userTagList = userTagsRepository.selectByUserId(null);
        List<Integer> tagIdList = userTagList.stream().map(e -> e.getTagId()).collect(Collectors.toList());
        List<UserItemTag> userItemTagList = new ArrayList<>();
        for (TagLibraryBO tagLibraryBO: tagLibraryBOS) {
            UserItemTag userItemTag = new UserItemTag();
            DictItemBO detail = dictItemRepository.detail(tagLibraryBO.getTagCategory());
            userItemTag.setTagCategoryName(detail == null ? "" :detail.getDictValue());
            tagLibraryBO.setUserSelected(tagIdList.contains(tagLibraryBO.getId()));
            userItemTag.setTagLibraryBO(tagLibraryBO);
            userItemTagList.add(userItemTag);
        }
        Map<String, List<UserItemTag>> dataMap = userItemTagList.stream()
                .collect(Collectors.groupingBy(UserItemTag::getTagCategoryName));
        return dataMap;
    }

    private void checkUniqueByTagTypeAndTagCategoryAndTagName(Integer id,TagLibraryParam tagLibraryParam, String self) throws BusinessException {
        TagLibraryQuery tagLibraryQuery = new TagLibraryQuery();
        tagLibraryQuery.setTagType(tagLibraryParam.getTagType());
        tagLibraryQuery.setTagCategory(tagLibraryParam.getTagCategory());
        tagLibraryQuery.setTagName(tagLibraryParam.getTagName());
        tagLibraryQuery.setSelf(self);
        if (Objects.nonNull(id)) {
            tagLibraryQuery.setId(id);
        }
       List<TagLibraryDO> tagLibraryDOS = tagLibraryRepository.selectByCondition(tagLibraryQuery);
        List<TagLibraryBO> tagLibraryBOS = tagLibraryConverter.doList2boList(tagLibraryDOS);

        if(!CollectionUtils.isEmpty(tagLibraryBOS)){
            throw new BusinessException("10014","标签数据不能重复");
        }
    }
}
